<?php
class Search_Model_Finder {

	protected $_searchIndexPath;	//path to initial data folder

	public function __construct() {
		$this->_searchIndexPath = ROOT_PATH . '/site/cache/search/';
		set_time_limit(900);
		$analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive();
		$analyzer->addFilter(new Search_Model_TokenFilter());
		Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);
	}

	public function clearindex(){
		$this->recursive_remove_directory($this->_searchIndexPath, TRUE);
	}
	
	/**
	 * Создает новый поисковой индекс
	 */
	public function updateIndex() {
		//удаляем существующий индекс, в большинстве случае эта операция с последующий созданием нового индекса работает гораздо быстрее
		$this->clearindex();
	  	try {
	  		$index = Zend_Search_Lucene::create($this->_searchIndexPath);
	  	} catch (Zend_Search_Lucene_Exception $e) {
	  	 	echo "<p class=\"ui-bad-message\">Не удалось создать поисковой индекс: {$e->getMessage()}</p>";
	  	}
		try {
			$cfg = Zend_Registry::get ( 'cnf' );
			$dir = $cfg->resources->frontController->moduleDirectory;
			$dir = $dir->toArray();
			$modules = array ();
			foreach ( $dir as $d ) {
				$modules [$d] = scandir ( $d );
			}
			foreach ( $modules as $dir => $mods ) {
				foreach ( $mods as $module ) {
					$file = $dir . '/' . $module . '/models/Search.php';
					if (! file_exists ( $file )) continue;
					$search_class_name = ucfirst($module) . '_Model_Search';
					$search = new $search_class_name();
					$list = $search->getData();
					if ($list) {
						foreach ($list as $item) {
							$doc = new Zend_Search_Lucene_Document();
							foreach ($search->_index_fields as $field) {
								$doc->addField(Zend_Search_Lucene_Field::Text($field, $item[$field], 'UTF-8'));
							}
							foreach ($search->_unindex_fields as $field) {
								$doc->addField(Zend_Search_Lucene_Field::unIndexed($field, $item[$field], 'UTF-8'));
							}
							
							$doc->addField(Zend_Search_Lucene_Field::unIndexed('url', $search->getUrl($item), 'UTF-8'));
							$doc->addField(Zend_Search_Lucene_Field::unIndexed('preview', $search->getPreview($item), 'UTF-8'));
							$doc->addField(Zend_Search_Lucene_Field::Text('section_name', $search->getSectionName($item), 'UTF-8'));
							$index->addDocument($doc);
						}
					}
				}
			}
		} catch (Zend_Search_Lucene_Exception $e) {
    		echo "<p class=\"ui-bad-message\">Ошибки индексации: {$e->getMessage()}</p>";
    	}
    	return;
    	//let's clean up some
    	$index->optimize();
	}

	/**
	 * recursive_remove_directory( directory to delete, empty )
	 * expects path to directory and optional TRUE / FALSE to empty
	 *
	 * @param $directory
	 * @param $empty TRUE - just empty directory
	 */
	function recursive_remove_directory($directory, $empty=FALSE) {
		if(substr($directory,-1) == '/') {
			$directory = substr($directory,0,-1);
		}
		if(!file_exists($directory) || !is_dir($directory)) {
			return FALSE;
		} elseif(is_readable($directory)) {
			$handle = opendir($directory);
			while (FALSE !== ($item = readdir($handle))) {
				if($item != '.' && $item != '..') {
					$path = $directory.'/'.$item;
					if(is_dir($path)) {
						$this->recursive_remove_directory($path);
					}else{
						unlink($path);
					}
				}
			}
			closedir($handle);
			if($empty == FALSE) {
				if(!rmdir($directory)) {
					return FALSE;
				}
			}
		}
		return TRUE;
	}

	/**
	 * Search by query
	 * 
	 * @param $query search query
	 * @return array Zend_Search_Lucene_Search_QueryHit
	 */
	public function search($query) {
		try{
			$index = Zend_Search_Lucene::open($this->_searchIndexPath);	
		} catch (Zend_Search_Lucene_Exception $e) {
			$this->updateIndex();
			$index = Zend_Search_Lucene::open($this->_searchIndexPath);
		}
		$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($query,"UTF-8");
		return $index->find($userQuery);
	}
}